﻿
// DrawTowerOfHanoiView.cpp: CDrawTowerOfHanoiView 类的实现
//

#include "pch.h"
#include "framework.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义，并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "DrawTowerOfHanoi.h"
#endif

#include "DrawTowerOfHanoiDoc.h"
#include "DrawTowerOfHanoiView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CDrawTowerOfHanoiView

IMPLEMENT_DYNCREATE(CDrawTowerOfHanoiView, CView)

BEGIN_MESSAGE_MAP(CDrawTowerOfHanoiView, CView)
	// 标准打印命令
	ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CDrawTowerOfHanoiView::OnFilePrintPreview)
	ON_WM_CONTEXTMENU()
	ON_WM_RBUTTONUP()
	ON_WM_PAINT()
	ON_COMMAND(TB_HANOI_ADD, &CDrawTowerOfHanoiView::onDrawHanoi)
	ON_COMMAND(TB_HANOI_SUB, &CDrawTowerOfHanoiView::onDrawHanoi1)
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONUP()
	ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()

// CDrawTowerOfHanoiView 构造/析构

void CDrawTowerOfHanoiView::OnPaint()
{
	CPaintDC dc(this); // 用于绘制的设备上下文

	// 创建一个内存设备上下文
	CDC memDC;
	memDC.CreateCompatibleDC(&dc);
	// 获取视图的客户区域大小
	CRect rect;
	GetClientRect(&rect); // 获取视图的客户区矩形

	int width = rect.Width();  // 客户区的宽度
	int height = rect.Height(); // 客户区的高度

	// 创建一个位图
	CBitmap bitmap;
	bitmap.CreateCompatibleBitmap(&dc, width, height);
	CBitmap* pOldBitmap = memDC.SelectObject(&bitmap);
	memDC.FillSolidRect(0, 0, width, height, RGB(255, 255, 255)); // 填充白色背景


	// 在内存DC中绘制
	OnDraw(&memDC); // 使用 OnDraw 在内存中绘制

	// 将内存DC的内容复制到屏幕DC
	dc.BitBlt(0, 0, width, height, &memDC, 0, 0, SRCCOPY);

	// 清理
	memDC.SelectObject(pOldBitmap);
}

CDrawTowerOfHanoiView::CDrawTowerOfHanoiView() noexcept
{
	// TODO: 在此处添加构造代码

}

CDrawTowerOfHanoiView::~CDrawTowerOfHanoiView()
{
}

BOOL CDrawTowerOfHanoiView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: 在此处通过修改
	//  CREATESTRUCT cs 来修改窗口类或样式

	return CView::PreCreateWindow(cs);
}

// CDrawTowerOfHanoiView 绘图

void CDrawTowerOfHanoiView::OnDraw(CDC* pDC)
{
	CDrawTowerOfHanoiDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	// 绘制汉诺塔
	CRect clientRect;
	GetClientRect(&clientRect);

	if (m_pCHanoiDraw == NULL)
		m_pCHanoiDraw = new CHanoiDraw(3);

	m_pCHanoiDraw->SetDC(pDC);

	int x0 = clientRect.TopLeft().x + 40;
	int y0 = clientRect.TopLeft().y + clientRect.Height() - 40;
	m_pCHanoiDraw->Init(x0,
		y0,
		clientRect.Width() - 40,
		clientRect.Height() - 40
	);


	// 绘制鼠标当前坐标
	CString xy;
	xy.Format(_T("%d,%d"), this->m_mousePoint.x-x0,y0- this->m_mousePoint.y);

	pDC->SetTextAlign(TA_CENTER);
	pDC->TextOutW(this->m_mousePoint.x, this->m_mousePoint.y - 10, xy);

	m_pCHanoiDraw->DrawPie(0, 0, m_pCHanoiDraw->m_curPieNO, this->m_mousePoint.x);

	// 如果完成了，要输出你赢了
	CString str(_T("你赢了！You win!"));
	if(m_pCHanoiDraw->isCompleted())

		pDC->TextOutW(this->m_mousePoint.x, this->m_mousePoint.y - 10, str);

}


// CDrawTowerOfHanoiView 打印
void CDrawTowerOfHanoiView::onDrawHanoi() {

	if (m_pCHanoiDraw) {
		m_pCHanoiDraw->SetCount(m_pCHanoiDraw->GetCount()+1);
		Invalidate();
	}
}
void CDrawTowerOfHanoiView::onDrawHanoi1() {

	if (m_pCHanoiDraw) {
		m_pCHanoiDraw->SetCount(m_pCHanoiDraw->GetCount()-1);
		Invalidate();
	}
}

void CDrawTowerOfHanoiView::OnFilePrintPreview()
{
#ifndef SHARED_HANDLERS
	AFXPrintPreview(this);
#endif
}

BOOL CDrawTowerOfHanoiView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// 默认准备
	return DoPreparePrinting(pInfo);
}

void CDrawTowerOfHanoiView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: 添加额外的打印前进行的初始化过程
}

void CDrawTowerOfHanoiView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: 添加打印后进行的清理过程
}

void CDrawTowerOfHanoiView::OnRButtonUp(UINT /* nFlags */, CPoint point)
{
	ClientToScreen(&point);
	OnContextMenu(this, point);
}

void CDrawTowerOfHanoiView::OnContextMenu(CWnd* /* pWnd */, CPoint point)
{
#ifndef SHARED_HANDLERS
	theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT, point.x, point.y, this, TRUE);
#endif
}


// CDrawTowerOfHanoiView 诊断

#ifdef _DEBUG
void CDrawTowerOfHanoiView::AssertValid() const
{
	CView::AssertValid();
}

void CDrawTowerOfHanoiView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CDrawTowerOfHanoiDoc* CDrawTowerOfHanoiView::GetDocument() const // 非调试版本是内联的
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDrawTowerOfHanoiDoc)));
	return (CDrawTowerOfHanoiDoc*)m_pDocument;
}
#endif //_DEBUG


// CDrawTowerOfHanoiView 消息处理程序


void CDrawTowerOfHanoiView::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值


	CView::OnMouseMove(nFlags, point);

	this->m_mousePoint = point;

	// 计算需要重绘的区域
	//CRect rect(point.x - 50, point.y - 50, point.x + 50, point.y + 50);
	//InvalidateRect(rect, TRUE); // 使指定区域无效，触发重绘

	Invalidate();
	
}


void CDrawTowerOfHanoiView::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	if (m_pCHanoiDraw) {
		if (0 != m_pCHanoiDraw->PutOnePie(point.x)) Invalidate();;
	}

	CView::OnLButtonUp(nFlags, point);
}


void CDrawTowerOfHanoiView::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值

	if (m_pCHanoiDraw ) {
		if (0 != m_pCHanoiDraw->GetOnePie(point.x)) Invalidate();;
	}

	CView::OnLButtonDown(nFlags, point);
}
